/***************************************
 * by Rodrigo Portillo to 3LM Informatica (www.3lminformatica.com.br);
 * portillo.designer@gmail.com
 * http://portillodesigner.blogspot.com
 * 
 * Was add a new propertie named "formato" with:
 * decimal = decimal number;
 * monetario = monetary format;
 * nenhum = null;
 * porcentagem = percent format.
 
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     NUMBER TEXT INPUT
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 O uso deste componente é livre. Criado por Rodrigo Portillo enquanto trabalhava
 na 3LM Informática.
 
 O intuíto é criar uma solução para números decimais e monetários.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 ****************************************/

/*****************************************
 VERSION CONTROL:
 
 v 0.1 - 
 
 ******************************************/
package classes
{
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.events.KeyboardEvent;
    
    import mx.controls.Label;
    import mx.controls.TextInput;
    import mx.events.FlexEvent;
    import mx.events.MoveEvent;
    import mx.events.ResizeEvent;
    import mx.formatters.CurrencyFormatter;
    
    /**
     *  @events
     */
    [Event("enterPressed", type="flash.events.Event" )]
    
    
    [IconFile("assets/icon.png")]
    public class NumberTextInput extends TextInput
    {
        
        //Criando os formatter
        private var formDecimal:CurrencyFormatter = null;
        private var formMoney:CurrencyFormatter = null;
        
        private var _label:DisplayObject;
        [Bindable]private var simboloMon:Label = new Label;
        
        [Bindable]private var pointDecimal:String = ",";
        
        
        /**
         *  @private
         */
        // Constants - Property formato
        public const FORM_DEC:String     = 'decimal'; //Valor Decimal com quatroDigitos
        public const FORM_POR:String     = 'porcentagem'; //VAlor Decimal de 2 digitos
        public const FORM_MON:String     = 'monetario'; //Valor Decimal com símbolo Real
        public const FORM_NONE:String     = 'nenhum'; //Padrão
        
        // Constants - Property moeda
        public const SIMB_REAL:String    = 'Real';
        public const SIMB_DOLL:String    = 'Dollar';
        public const SIMB_EURO:String    = 'Euro';
        public const SIMB_POUND:String    = 'Pounds';
        public const SIMB_CENT:String    = 'Cents';
        public const SIMB_YEN:String    = 'Yens';
        public const SIMB_CUR:String    = 'Current';
        public const SIMB_DRAC:String    = 'Dracma';
        public const SIMB_RUPEE:String    = 'Rupees';
        public const SIMB_PESE:String    = 'Pesetas';
        public const SIMB_FRANC:String    = 'Franchs';
        public const SIMB_PESO:String    = 'Peso';
        
        // Constants separator
        public const DEC_VIR:String    = 'comma';
        public const DEC_DOT:String    = 'dot';
        
        /**
         *  @constructor
         */
        public function NumberTextInput2()
        {
            super();
            
            //this.addEventListener(KeyboardEvent.KEY_UP, apertadoVirgula) //Ativar a função do vírgula
            // Event Change
            this.addEventListener(Event.CHANGE,numChange);
            this.addEventListener(FlexEvent.CREATION_COMPLETE,numChange);
            this.addEventListener(FocusEvent.FOCUS_OUT,numChange);//Formatação
            
            this.addEventListener(MoveEvent.MOVE,numChange)//Ao mudar de posição
            this.addEventListener(ResizeEvent.RESIZE,numChange)//Ao mudar de Tamanho.
            // Event Creation Complete
            this.addEventListener(FlexEvent.CREATION_COMPLETE,creationComplete);
        }
        
        /**
         *  Auto execute validations properties
         */
        private function creationComplete(event:Event):void
        {
            simbolo(event);
            this.setStyle("textAlign","right");
            
            if (decimalSeparator == "," || pointDecimal == ",")
            {
                restrict = "0-9/,"
                this.addEventListener(KeyboardEvent.KEY_DOWN, apertadoVirgula) //Ativar a função do vírgula
            }
            if (decimalSeparator == "." || pointDecimal == ".")
            {
                restrict = "0-9/."
                this.addEventListener(KeyboardEvent.KEY_DOWN, apertadoPonto) //Ativar a função do vírgula
            }
            pointDecimal = ",";
            separa(event);
        }
        
        
        /**
         * @public 
         * CAPS TYPE PROPERTY:
         * Auto change the text case.
         * NORMAL : No change [DEFAULT]
         * LOWERCASE : Auto change to lowercase
         * UPPERCASE : Auto change to uppercase
         * INIT : Auto change first char to uppercase
         */
        private var _formato:String = FORM_NONE;
        [Inspectable("nenhum,decimal,porcentagem,monetario", defaultValue="nenhum",category="General")]
        public function get formato():String
        {
            return formato;
        }
        public function set formato(value:String):void
        {
            switch (value)
            {
                case FORM_NONE:
                {
                    break;
                }
                case FORM_DEC:
                {
                    break;
                }
                case FORM_POR:
                {
                    break;
                }
                case FORM_MON:
                {
                    break;
                }
                default:
                {
                    var message:String = resourceManager.getString("rpc", "invalidResultFormat",[ value,
                        FORM_NONE,FORM_DEC,FORM_POR,FORM_MON]);
                    throw new ArgumentError(message);
                }
            }
            
            _formato = value;
        }
        
        
        //--------------------------------------------------------
        //    FORMATO = FORMAT AREA
        //--------------------------------------------------------
        [Bindable]private var pressionouVirgula:Boolean;
        [Bindable]private var pressionouPonto:Boolean;
        [Bindable]private var pressionouBackspace:Boolean;
        
        [Bindable]private var posicaoX:Number;
        [Bindable]private var posicaoY:Number;
        
        [Bindable]private var symbol:String = "R$";
        [Bindable]private var decimalSeparator:String = ",";
        
        [Bindable]private var decimalPrecision:Number = 2;
        
        
        /**
         * Controlar Vírgula
         * e Backspace
         */
        private function apertadoVirgula(event:KeyboardEvent):void{
            if (event.keyCode == 188 || event.keyCode == 110)
            {
                pressionouVirgula = true;
                return;
            }
            else if (event.keyCode == 8)
            {
                pressionouBackspace = true;
                return;
            }
            else
            {    
                pressionouVirgula = false
                pressionouBackspace = false;
                return;
            }
        }
        
        /**
         * Controlar Vírgula
         * e Backspace
         */
        private function apertadoPonto(event:KeyboardEvent):void{
            if (event.keyCode == 190 || event.keyCode == 194)
            {
                pressionouPonto = true;
                return;
            }
            else if (event.keyCode == 8)
            {
                pressionouBackspace = true;
                return;
            }
            else
            {    
                pressionouPonto = false
                pressionouBackspace = false;
                return;
            }
        }
        
        private function numChange(event:Event):void
        {    
            formDecimal = new CurrencyFormatter(); // Formatação Decimal
            formDecimal.currencySymbol = "";
            
            formDecimal.useThousandsSeparator = false;
            formDecimal.decimalSeparatorFrom = decimalSeparator;
            formDecimal.decimalSeparatorTo = decimalSeparator;
            
            posicaoX    =    this.x;
            posicaoY    =    this.y;
            
            switch (this._formato)
            {
                
                case FORM_NONE:
                {
                    break;
                }
                case FORM_DEC:
                {
                    formDecimal.precision = 4;
                    formDecimal.decimalSeparatorFrom = pointDecimal;
                    formDecimal.decimalSeparatorTo = pointDecimal;
                    
                    //Se por acaso for pressionado o BackSpace |If backspace is pressed
                    if(pressionouBackspace == true) 
                    {
                        return; //Isso evita que ele formate quando apagar alguma coisa | Dont let backspace format something
                    }
                    
                    // Caso esteja vazio | If Empty
                    if(this.text == "")
                    {
                        this.text = "0"+pointDecimal+"0000"  // Mantém 0,00 como valor mínimo preenchido
                    }
                    
                    // Quando o vírgula for pressionado
                    if(pressionouVirgula == true || pressionouPonto == true) 
                    {
                        //Verificar se o valor é diferente de zero
                        if (parseInt(this.text.substr(this.text.length-4,4)) !== 0)
                        {    
                            //Verigicar se o valor que é diferente de zero tem vírgula
                            if (this.text.substr(this.text.length-1,1) == pointDecimal)
                            {
                                this.text = this.text.substr(0,this.text.length-1)
                                return // Dessa forma evitamos que haja um vírgula no final e perca a formatação caso a pessoa aperte vírgula após ter colocado o valor decimal
                            }
                            
                            this.text = this.text.replace(pointDecimal,""); // Apagar os vírgulas extras que possam tentar ser digitados
                            
                            //Fazer com que o vírgula sempre seja posicionado nos antipenultimos caracteres
                            this.text = this.text.substring(0,this.text.length-5) + pointDecimal + this.text.substring(this.text.length-4,this.text.length); // Criar um novo vírgula no lugar
                            
                            // Deixar cursor de digitação após o vírgula.
                            this.setSelection(this.text.length-4,this.text.length); 
                            
                            break;
                            return;
                        }
                        
                        this.text = this.text.replace(pointDecimal,""); // Apagar os vírgulas desnecessários
                        
                        // Deixar cursor de digitação após o vírgula.
                        this.setSelection(this.text.length-4,this.text.length);
                        
                        //Aplicar a formatação
                        this.text = formDecimal.format(this.text);//Formatar
                        
                        break;
                    }
                    if(this.text == "0"+pointDecimal+"0000") // Caso esteja com a casa 0,00
                    {
                        this.setSelection(0,this.text.length);
                        break;
                    }
                    
                    this.text = formDecimal.format(this.text);//Formatar
                    
                    break;
                }
                    //-----------------------
                    // Caso seja Porcentagem
                    //-----------------------
                case FORM_POR:
                {
                    formDecimal.precision = decimalPrecision;
                    
                    var index:Number         = this.parent.getChildIndex(this);
                    
                    simboloMon.text         = "%";
                    simboloMon.x             = posicaoX;
                    simboloMon.y              = posicaoY;
                    simboloMon.height         = this.height;
                    
                    simboloMon.styleName     = this.styleName;
                    
                    simboloMon.setStyle("paddingTop",2);
                    simboloMon.setStyle("paddingLeft",2);
                    
                    this.setStyle("paddingLeft",simboloMon.width+15);
                    
                    this.parent.addChild(simboloMon);
                    
                    
                    //Se por acaso for pressionado o BackSpace
                    if(pressionouBackspace == true) 
                    {
                        return; //Isso evita que ele formate quando apagar alguma coisa 
                    }
                    
                    // Caso esteja vazio
                    if(this.text == "")
                    {
                        this.text = "0"+decimalSeparator+"00"  // Mantém 0,00 como valor mínimo preenchido
                    }
                    
                    // Quando o vírgula for pressionado
                    if(pressionouVirgula == true || pressionouPonto == true) 
                    {
                        //Verificar se o valor é diferente de zero
                        if (parseInt(this.text.substr(this.text.length-2,2)) !== 0)
                        {    
                            //Verigicar se o valor que é diferente de zero tem vírgula
                            if (this.text.substr(this.text.length-1,1) == decimalSeparator)
                            {
                                this.text = this.text.substr(0,this.text.length-1)
                                return // Dessa forma evitamos que haja um vírgula no final e perca a formatação caso a pessoa aperte vírgula após ter colocado o valor decimal
                            }
                            
                            this.text = this.text.replace(decimalSeparator,""); // Apagar os vírgulas extras que possam tentar ser digitados
                            
                            //Fazer com que o vírgula sempre seja posicionado nos antipenultimos caracteres
                            this.text = this.text.substring(0,this.text.length-3) + decimalSeparator + this.text.substring(this.text.length-2,this.text.length); // Criar um novo vírgula no lugar
                            
                            // Deixar cursor de digitação após o vírgula.
                            this.setSelection(this.text.length-2,this.text.length); 
                            
                            break;
                            return;
                        }
                        
                        this.text = this.text.replace(decimalSeparator,""); // Apagar os vírgulas desnecessários
                        
                        // Deixar cursor de digitação após o vírgula.
                        this.setSelection(this.text.length-2,this.text.length);
                        
                        //Aplicar a formatação
                        this.text = formDecimal.format(this.text);//Formatar
                        
                        break;
                    }
                    if(this.text == "0"+decimalSeparator+"00") // Caso esteja com a casa 0,00
                    {
                        this.setSelection(0,this.text.length);
                        break;
                    }
                    
                    this.text = formDecimal.format(this.text);//Formatar
                    break;
                }
                    //-----------------------
                    //    CASO SEJA MONETARIO
                    //-----------------------
                case FORM_MON:
                {
                    formDecimal.precision     = decimalPrecision;
                    var index:Number         = this.parent.getChildIndex(this);
                    
                    simboloMon.text         = symbol;
                    simboloMon.x             = posicaoX;
                    simboloMon.y              = posicaoY;
                    simboloMon.height         = this.height;
                    
                    simboloMon.styleName     = this.styleName;
                    
                    simboloMon.setStyle("paddingTop",2);
                    simboloMon.setStyle("paddingLeft",2);
                    
                    this.setStyle("paddingLeft",simboloMon.width+15);
                    
                    this.parent.addChild(simboloMon);
                    
                    
                    //Se por acaso for pressionado o BackSpace
                    if(pressionouBackspace == true) 
                    {
                        return; //Isso evita que ele formate quando apagar alguma coisa 
                    }
                    
                    // Caso esteja vazio
                    if(this.text == "")
                    {
                        this.text = "0"+decimalSeparator+"00"  // Mantém 0,00 como valor mínimo preenchido
                    }
                    
                    // Quando o vírgula for pressionado
                    if(pressionouVirgula == true || pressionouPonto == true) 
                    {
                        //Verificar se o valor é diferente de zero
                        if (parseInt(this.text.substr(this.text.length-2,2)) !== 0)
                        {    
                            //Verigicar se o valor que é diferente de zero tem vírgula
                            if (this.text.substr(this.text.length-1,1) == decimalSeparator)
                            {
                                this.text = this.text.substr(0,this.text.length-1)
                                return // Dessa forma evitamos que haja um vírgula no final e perca a formatação caso a pessoa aperte vírgula após ter colocado o valor decimal
                            }
                            
                            this.text = this.text.replace(decimalSeparator,""); // Apagar os vírgulas extras que possam tentar ser digitados
                            
                            //Fazer com que o vírgula sempre seja posicionado nos antipenultimos caracteres
                            this.text = this.text.substring(0,this.text.length-3) + decimalSeparator + this.text.substring(this.text.length-2,this.text.length); // Criar um novo vírgula no lugar
                            
                            // Deixar cursor de digitação após o vírgula.
                            this.setSelection(this.text.length-2,this.text.length); 
                            
                            break;
                            return;
                        }
                        
                        this.text = this.text.replace(decimalSeparator,""); // Apagar os vírgulas desnecessários
                        
                        // Deixar cursor de digitação após o vírgula.
                        this.setSelection(this.text.length-2,this.text.length);
                        
                        //Aplicar a formatação
                        this.text = formDecimal.format(this.text);//Formatar
                        
                        break;
                    }
                    if(this.text == "0"+decimalSeparator+"00") // Caso esteja com a casa 0,00
                    {
                        this.setSelection(0,this.text.length);
                        break;
                    }
                    
                    this.text = formDecimal.format(this.text);//Formatar
                    break;
                }
                default:
                {
                }
            }
        }
        
        //--------------------------------------------------------
        //    FORMATO = FORMAT AREA FIM END
        //--------------------------------------------------------
    
        //---------------------------------------------------------
        // Moeda = Monetary
        //---------------------------------------------------------
        private var _moeda:String = SIMB_REAL;
        [Inspectable("Real,Dollar,Euro,Pounds,Cents,Yens,Current,Dracma,Rupees,Pesetas,Franchs,Peso", defaultValue="Real",category="General")]
        public function get moeda():String
        {
            return moeda;
        }
        public function set moeda(value:String):void
        {
            switch (value)
            {
                case SIMB_REAL:
                {
                    symbol = "R$";
                    decimalSeparator = ",";
                    break;
                }
                    case SIMB_DOLL:
                {
                    symbol = "$";
                    decimalSeparator = ".";
                    break;
                }
                    case SIMB_EURO:
                {
                    symbol = "€";
                    decimalSeparator = ".";
                    break;
                }
                    case SIMB_POUND:
                {
                    symbol = "£";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_CENT:
                {
                    symbol = "¢";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_YEN:
                {
                    symbol = "¥";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_CUR:
                {
                    symbol = "¤";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_DRAC:
                {
                    symbol = "₯";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_RUPEE:
                {
                    symbol = "₨";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_PESE:
                {
                    symbol = "₧";
                    decimalSeparator = ",";
                    break;
                }
                case SIMB_FRANC:
                {
                    symbol = "₣";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_PESO:
                {
                    symbol = "₱";
                    decimalSeparator = ",";
                    break;
                }
                default:
                {
                    var message:String = resourceManager.getString("rpc", "invalidResultFormat",[ value,
                        SIMB_REAL,SIMB_DOLL,SIMB_EURO,SIMB_POUND,SIMB_CENT,SIMB_YEN,SIMB_CUR,SIMB_DRAC,SIMB_RUPEE,SIMB_PESE,SIMB_FRANC,SIMB_PESO]);
                    throw new ArgumentError(message);
                }
            }
            
            _moeda = value;
        }
    /**
     * Define as propriedades de símbolos e formatos
     * Symbols and formats;
     */
    private function simbolo(event:Event):void
        {            
            switch (this._moeda)
            {
                
                case SIMB_REAL:
                {
                    symbol = "R$";
                    decimalSeparator = ",";
                    break;
                }
                case SIMB_DOLL:
                {
                    symbol = "$";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_EURO:
                {
                    symbol = "€";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_POUND:
                {
                    symbol = "£";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_CENT:
                {
                    symbol = "¢";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_YEN:
                {
                    symbol = "¥";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_CUR:
                {
                    symbol = "¤";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_DRAC:
                {
                    symbol = "₯";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_RUPEE:
                {
                    symbol = "₨";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_PESE:
                {
                    symbol = "₧";
                    decimalSeparator = ",";
                    break;
                }
                case SIMB_FRANC:
                {
                    symbol = "₣";
                    decimalSeparator = ".";
                    break;
                }
                case SIMB_PESO:
                {
                    symbol = "₱";
                    decimalSeparator = ",";
                    break;
                }
            }
        }
        //-------------------------
        //    Separator
        //-------------------------
        private var _decDot:String = DEC_VIR;
        [Inspectable("comma,dot", defaultValue="comma",category="General")]
        public function get separator():String
        {
            return separator;
        }
        public function set separator(value:String):void
        {
            switch (value)
            {
                case DEC_VIR:
                {
                    pointDecimal = ",";
                    break;
                }
                case DEC_DOT:
                {
                    pointDecimal = ".";
                    break;
                }
                default:
                {
                    var message:String = resourceManager.getString("rpc", "invalidResultFormat",[ value,
                        DEC_VIR,DEC_DOT]);
                    throw new ArgumentError(message);
                }
            }
            
            _decDot = value;
        }
        /**
         * Define as propriedades de símbolos e formatos
         * Symbols and formats;
         */
        private function separa(event:Event):void
        {            
            switch (this._decDot)
            {
                
                case DEC_VIR:
                {
                    pointDecimal = ",";
                    break;
                }
                case DEC_DOT:
                {
                    pointDecimal = ".";
                    break;
                }
            }
        }
    
    }
}

